package org.example.rpc;

import com.rabbitmq.client.*;
import org.example.constant.Constants;

import java.io.IOException;
import java.util.UUID;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeoutException;

public class Client {
    public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
        //1. 建立连接
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost(Constants.HOST);
        connectionFactory.setPort(Constants.PORT); //需要提前开放端口号
        connectionFactory.setUsername(Constants.USER_NAME);//账号
        connectionFactory.setPassword(Constants.PASSWORD);  //密码
        connectionFactory.setVirtualHost(Constants.VIRTUAL_HOST); //虚拟主机
        Connection connection = connectionFactory.newConnection();
        //2. 开启信道
        Channel channel = connection.createChannel();
        //首先的话，在发送消息的时候，先给那个请求的队列发送
        channel.queueDeclare(Constants.RPC_REQUEST_QUEUE, true, false, false, null);
        channel.queueDeclare(Constants.RPC_RESPONSE_QUEUE, true, false, false, null);
        //要写配置文件了
        String msg="hello rpc";
        //请求信息的唯一标识
        String correlationID = UUID.randomUUID().toString();
        //给请求设置相关的属性
        AMQP.BasicProperties props=new AMQP.BasicProperties().builder()
                .correlationId(correlationID)
                .replyTo(Constants.RPC_RESPONSE_QUEUE)
                .build();
        channel.basicPublish("",Constants.RPC_REQUEST_QUEUE,props,msg.getBytes());

        //4.响应消息
        final BlockingQueue<String> responseQueue = new LinkedBlockingQueue<String>();
        DefaultConsumer consumer = new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                //首先将消息打印出来
                System.out.println(new String(body));
                if(properties.getCorrelationId().equals(correlationID)){
                    //这个id是用来进行校验看这两个消息是不是一对
                    responseQueue.offer(new String(body));
                }
            }
        };
        //只有在消费的时候才设置手动确认还是自动确认
        channel.basicConsume(Constants.RPC_RESPONSE_QUEUE,true,consumer);
        String result = responseQueue.take();
        System.out.println("[RPC Client 响应结果]:"+ result);
    }
}
